package com.relife.sys.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.relife.common.exception.BusinessException;
import com.relife.common.model.Client;
import com.relife.common.model.ClientManager;
import com.relife.common.model.Page;
import com.relife.common.utils.ReflectUtil;
import com.relife.common.utils.StringUtil;
import com.relife.common.utils.SysConfig;
import com.relife.core.entity.*;
import com.relife.core.qbc.QbcQuery;
import com.relife.core.service.BaseService;
import com.relife.core.service.SerialService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;


@Service
@Transactional
public class DepartService extends BaseService {

	@Autowired
	private SerialService serialService;
	@Autowired
	private IdentityService identityService;

	public void saveDepart(DepartmentEntity dept) {
		if (dept.getParent() != null && dept.getParent().getId() == null) {
			dept.setParent(null);
		}

		if (dept.getType().intValue() == 1) {
			dept.setParent(null);
		}

		if (StringUtil.isEmpty(dept.getId())) {
			CodeEntity code = ClientManager.getInstance().getCode("departType", dept.getType().toString());
			String departCode = serialService.hasDepartCode(code.getVal());
			if (dept.getParent() != null) {
				DepartmentEntity parent = this.get(DepartmentEntity.class, dept.getParent().getId());
				dept.setDepartCode(parent.getDepartCode() + departCode);
			} else {
				dept.setDepartCode(departCode);
			}
			this.save(dept);
			dept.setDepCode(dept.getDepartCode());
		} else {
			DepartmentEntity depart = this.get(DepartmentEntity.class, dept.getId());

			if (depart.getType().intValue() != dept.getType().intValue() || StringUtil.isEmpty(dept.getDepartCode())) {
				CodeEntity code = ClientManager.getInstance().getCode("departType", dept.getType().toString());
				String departCode = serialService.hasDepartCode(code.getVal());
				if (dept.getParent() != null) {
					DepartmentEntity parent = this.get(DepartmentEntity.class, dept.getParent().getId());
					depart.setDepartCode(parent.getDepartCode() + departCode);
				} else {
					depart.setDepartCode(departCode);
				}
			}
			dept.setDepartCode(null);
			ReflectUtil.copyNotNullPro2Bean(dept, depart);
			depart.setDepCode(depart.getDepartCode());
		}
	}

	/**
	 * 组织机构角色编辑
	 * 
	 * @author WU
	 * @date 2016年5月16日 下午4:21:48
	 */
	public void saveDepartRole(RoleEntity role, String[] perm, String[] funIds) {
		List<FunctionEntity> list = new ArrayList<FunctionEntity>();
		if (funIds != null) {
			for (int i = 0; i < funIds.length; i++) {
				list.add(new FunctionEntity(funIds[i]));
			}
		}
		DepartmentEntity depart = get(DepartmentEntity.class, "departCode", role.getDepart().getDepartCode());

		role.setGroupId(depart.getDepartCode() + role.getDutyCode());
		role.setDepCode(depart.getDepartCode());
		role.setDepart(depart);
		role.setFunctionList(list);
		this.saveOrUpdate(role);

		if (role.getId() != null) {
			this.deleteList(getList(RolePermissionEntity.class, "role.id", role.getId()));
		}

		if (perm != null) {
			for (int i = 0; i < perm.length; i++) {
				RolePermissionEntity rp = new RolePermissionEntity();
				rp.setRole(role);
				rp.setPermission(new PermissionEntity(perm[i]));
				this.save(rp);
			}
		}

		long groups = identityService.createGroupQuery().groupId(role.getGroupId()).count();
		if (groups == 0) {
			Group group = identityService.newGroup(role.getGroupId());
			group.setName(role.getName());
			group.setType(depart.getName());
			identityService.saveGroup(group);
		}
	}

	/**
	 * 保存部门用户
	 * 
	 * @author WU
	 * @date 2017年3月31日 上午10:58:35
	 */
	public void saveDepartUser(String departId, String[] user, String[] role) {
		if (user == null || user.length == 0) {
			throw new BusinessException("请先选择用户!");
		}

		for (int i = 0; i < user.length; i++) {
			UserEntity u = this.get(UserEntity.class, user[i]);
			DepartmentEntity depart = this.get(DepartmentEntity.class, departId);

			List<DepartUserEntity> list = this.getList(DepartUserEntity.class, "user.id", u.getId());
			String depCode = "";
			for (int j = 0; j < list.size(); j++) {
				depCode += j == 0 ? list.get(j).getDepart().getDepartCode() : ("," + list.get(j).getDepart().getDepartCode());
			}
			if (list.size() == 0) {
				depCode = depart.getDepartCode();
			}
			u.setDepCode(depCode);

			long users = identityService.createUserQuery().userId(u.getId()).count();
			if (users == 0) {
				User actu = identityService.newUser(u.getId());
				actu.setFirstName(u.getName());
				actu.setLastName(u.getName());
				actu.setEmail(u.getPhone());
				identityService.saveUser(actu);
			}

			QbcQuery qbc = new QbcQuery(DepartUserEntity.class);
			qbc.add(Restrictions.eq("user.id", user[i]));
			qbc.add(Restrictions.eq("depart.id", departId));
			DepartUserEntity du = this.get(qbc);
			if (du == null) {
				du = new DepartUserEntity();
				du.setDepart(depart);
				du.setUser(new UserEntity(user[i]));
				du.setDepCode(depart.getDepartCode());
				this.save(du);
			}

			QbcQuery urQbc = new QbcQuery(UserRoleEntity.class);
			urQbc.add(Restrictions.eq("depart.id", departId));
			urQbc.add(Restrictions.eq("user.id", user[i]));
			this.deleteList(getList(urQbc));

			if (role != null && role.length > 0) {
				for (int j = 0; j < role.length; j++) {
					RoleEntity r = this.get(RoleEntity.class, role[j]);
					long groups = identityService.createGroupQuery().groupId(r.getGroupId()).count();
					if (groups == 0) {
						Group group = identityService.newGroup(r.getGroupId());
						group.setName(r.getName());
						group.setType(r.getDepart().getName());
						identityService.saveGroup(group);
					}
					String sql = "select count(*) from act_id_membership t where t.user_id_= ? and t.group_id_= ?";
					if (this.getCountJdbc(sql, du.getUser().getId(), r.getGroupId()) == 0) {
						identityService.createMembership(du.getUser().getId(), r.getGroupId());
					}
					UserRoleEntity ur = new UserRoleEntity();
					ur.setRole(new RoleEntity(role[j]));
					ur.setDepart(depart);
					ur.setDepCode(depart.getDepartCode());
					ur.setUser(du.getUser());
					this.save(ur);
				}
			}

		}
	}

	/**
	 * 
	 * @author WU
	 * @date 2017年4月1日 下午2:18:12
	 * @param du
	 */
	public void delDepartUser(DepartUserEntity du) {

		du = this.get(DepartUserEntity.class, du.getId());

		QbcQuery qbc = new QbcQuery(UserRoleEntity.class);
		qbc.add(Restrictions.eq("depart.id", du.getDepart().getId()));
		qbc.add(Restrictions.eq("user.id", du.getUser().getId()));
		this.deleteList(this.getList(qbc));

		identityService.deleteUser(du.getUser().getId());

		this.delete(du);
	}

	/**
	 * 数据更新(角色上添加部门ID)
	 * 
	 * @author WU
	 * @date 2017年4月1日 下午2:58:07
	 */
	public void updateRole() {
		List<DepartUserEntity> list = this.getList(DepartUserEntity.class, Order.asc("id"));
		for (int i = 0; i < list.size(); i++) {
			QbcQuery qbc = new QbcQuery(UserRoleEntity.class);
			qbc.add(Restrictions.eq("user.id", list.get(i).getUser().getId()));
			qbc.add(Restrictions.isNull("depart.id"));
			List<UserRoleEntity> duList = this.getList(qbc);
			for (int j = 0; j < duList.size(); j++) {
				duList.get(j).setDepart(list.get(i).getDepart());
			}
		}
	}

	/**
	 * 部门用户列表
	 * 
	 * @author WU
	 * @date 2017年4月1日 下午4:35:16
	 * @param where
	 * @param page
	 * @param req
	 */
	public void departUserGird(StringBuffer where, Page page, HttpServletRequest req) {
		String sql = SysConfig.getReportSql();
		String departId = req.getParameter("departId");
		List<Object> param = new ArrayList<Object>();
		if (StringUtil.isNotEmpty(departId)) {
			sql = String.format(sql, "and ur.depart_id=?", "and du.depart_id=?");
			sql += " and t.depart_id=? ";
			param.add(departId);
			param.add(departId);
			param.add(departId);
		} else {
			sql = String.format(sql, "", "");
		}
		QbcQuery.getWhere(where, param, req.getParameterMap(), page);
		getPage(sql + where.toString(), page, param.toArray());
	}

	/**
	 * 角色菜单
	 * 
	 * @param role
	 * @return
	 */
	public JSONArray departRole(RoleEntity role) {
		Client client = ClientManager.getInstance().getClientSession();
		StringBuffer sql = new StringBuffer();
		sql.append("select distinct f.id,f.name,f.parentid,(case when fu.fun_id is not null then 1 else 0 end) checked,f.orderby");
		sql.append(" from sys_function f left join sys_function_role fr on fr.fun_id=f.id");
		sql.append(" left join (select t.fun_id from sys_function_role t where t.role_id=?) fu on fu.fun_id=f.id ");
		sql.append(" where 1=1");
		List<Object> param = new ArrayList<Object>();
		param.add(role.getId() == null ? "1" : role.getId());

		if (!client.getUser().isAdmin()) {
			sql.append(" and fr.role_id in(select ur.role_id from sys_user_role ur where ur.user_id=?)");
			param.add(client.getUser().getId());
		}
		sql.append(" order by f.orderby");

		if (role.getId() != null) {
			role = this.get(RoleEntity.class, role.getId());
		}
		List<Map<String, Object>> list = this.getList(sql.toString(), param.toArray());
		JSONArray array = new JSONArray();
		for (int i = 0; i < list.size(); i++) {
			JSONObject obj = new JSONObject();
			obj.put("id", list.get(i).get("id"));
			obj.put("name", list.get(i).get("name"));
			obj.put("pId", list.get(i).get("parentid"));
			obj.put("checked", 1 == Integer.valueOf(list.get(i).get("checked").toString()));
			obj.put("open", true);
			array.add(obj);
		}
		return array;
	}
}
